package com.sangshen.ad_jg_flutter_sdk;

import android.util.Log;
import android.view.View;
import android.widget.FrameLayout;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import java.util.List;
import android.os.Handler;
import android.os.Looper;

import cn.jiguang.jgssp.ad.ADJgNativeAd;
import cn.jiguang.jgssp.ad.data.ADJgNativeAdInfo;
import cn.jiguang.jgssp.ad.data.ADJgNativeExpressAdInfo;
import cn.jiguang.jgssp.ad.entity.ADJgAdSize;
import cn.jiguang.jgssp.ad.entity.ADJgExtraParams;
import cn.jiguang.jgssp.ad.error.ADJgError;
import cn.jiguang.jgssp.ad.listener.ADJgNativeAdListener;
import cn.jiguang.jgssp.util.ADJgAdUtil;
import cn.jiguang.jgssp.util.ADJgDisplayUtil;
import cn.jiguang.jgssp.util.ADJgViewUtil;
import io.flutter.plugin.platform.PlatformView;

public class FlutterNativeAd extends FlutterAd implements PlatformView, FlutterDestroyableAd {

    @NonNull
    private final AdInstanceManager manager;
    /**
     * 广告位id
     */
    @NonNull
    private final String adPosId;
    /**
     * 场景id可选
     */
    @NonNull
    private final String sceneId;
    /**
     * 广告宽
     */
    @NonNull
    private final int adWidth;
    /**
     * 广告高
     */
    @NonNull
    private int adHeight;
    /**
     * 广告容器
     */
    private FrameLayout flContainer;
    /**
     * 广告对象
     */
    private ADJgNativeAd adADJgNativeAd;

    static class Builder {
        @Nullable
        private AdInstanceManager manager;
        @Nullable
        private String adPosId;
        @Nullable
        private String sceneId;
        @Nullable
        private Double adWidth;
        @Nullable
        private Double adHeight;

        public Builder setManager(@NonNull AdInstanceManager manager) {
            this.manager = manager;
            return this;
        }

        public Builder setAdPosId(@NonNull String adPosId) {
            this.adPosId = adPosId;
            return this;
        }

        public Builder setAdWidth(@NonNull Double adWidth) {
            this.adWidth = adWidth;
            return this;
        }

        public Builder setAdHeight(@NonNull Double adHeight) {
            this.adHeight = adHeight;
            return this;
        }

        public Builder setSceneId(@NonNull String sceneId) {
            this.sceneId = sceneId;
            return this;
        }

        FlutterNativeAd build() {
            if (manager == null) {
                throw new IllegalStateException("AdInstanceManager cannot not be null.");
            } else if (adPosId == null) {
                throw new IllegalStateException("adPosId cannot not be null.");
            }

            final FlutterNativeAd nativeAd = new FlutterNativeAd(manager, adPosId, sceneId, adWidth, adHeight);
            return nativeAd;
        }
    }

    private FlutterNativeAd(
            @NonNull AdInstanceManager manager, @NonNull String adPosId, @NonNull String sceneId, @NonNull Double adWidth, @NonNull Double adHeight) {
        this.manager = manager;
        this.adPosId = adPosId;
        this.sceneId = sceneId;
        this.adWidth = ADJgDisplayUtil.dp2px(new Double(adWidth).intValue());
        this.adHeight = ADJgDisplayUtil.dp2px(new Double(adHeight).intValue());

        flContainer = new FrameLayout(manager.activity);

    }

    @Override
    void load() {
        // 创建信息流广告实例
        adADJgNativeAd = new ADJgNativeAd(manager.activity);
        // 创建额外参数实例
        ADJgExtraParams extraParams = new ADJgExtraParams.Builder()
                // 设置整个广告视图预期宽高(目前仅头条平台需要，没有接入头条可不设置)，单位为px，高度如果小于等于0则高度自适应
                .adSize(new ADJgAdSize(adWidth, 0))
                // 设置广告视图中MediaView的预期宽高(目前仅Inmobi平台需要,Inmobi的MediaView高度为自适应，没有接入Inmobi平台可不设置)，单位为px
                .nativeAdMediaViewSize(new ADJgAdSize((int) (adWidth - 24 * manager.activity.getResources().getDisplayMetrics().density)))
                // 设置信息流广告适配播放是否静音，默认静音，目前广点通、百度、汇量、快手、Admobile支持修改
                .nativeAdPlayWithMute(ADJgDemoConstant.NATIVE_AD_PLAY_WITH_MUTE)
                .build();
        // 设置一些额外参数，有些平台的广告可能需要传入一些额外参数，如果有接入头条、Inmobi平台，如果包含这些平台该参数必须设置
        adADJgNativeAd.setLocalExtraParams(extraParams);

        // 设置仅支持的广告平台，设置了这个值，获取广告时只会去获取该平台的广告，null或空字符串为不限制，默认为null，方便调试使用，上线时建议不设置
        adADJgNativeAd.setOnlySupportPlatform(ADJgDemoConstant.NATIVE_AD_ONLY_SUPPORT_PLATFORM);
        // 设置广告监听
        adADJgNativeAd.setListener(new ADJgNativeAdListener() {
            @Override
            public void onRenderFailed(ADJgNativeAdInfo adADJgNativeAdInfo, ADJgError adADJgError) {
                Log.d(ADJgDemoConstant.TAG, "onRenderFailed: " + adADJgError.toString());
                if (adADJgError != null) {
                    Log.d(ADJgDemoConstant.TAG, "onAdFailed: " + adADJgError.toString());
                    manager.onAdFailed(FlutterNativeAd.this, adADJgError);
                }
            }

            @Override
            public void onRenderSuccess(ADJgNativeAdInfo adADJgNativeAdInfo) {
                Log.d(ADJgDemoConstant.TAG, "onRenderSuccess: " + adADJgNativeAdInfo.hashCode());
                int[] size = unDisplayViewSize(flContainer);
                callbackReceived(size);
            }

            @Override
            public void onAdReceive(List<ADJgNativeAdInfo> adInfoList) {
                Log.d(ADJgDemoConstant.TAG, "onAdReceive: " + adInfoList.size());
                if (adInfoList != null && adInfoList.size() > 0) {
                    ADJgNativeAdInfo adADJgNativeAdInfo = adInfoList.get(0);
                    manager.onAdReceive(
                            FlutterNativeAd.this,
                            adADJgNativeAdInfo.getPlatform(),
                            adADJgNativeAdInfo.getEcpmPrecision(),
                            adADJgNativeAdInfo.getECPM()
                    );
                    if (adADJgNativeAdInfo instanceof ADJgNativeExpressAdInfo) {
                        showNativeAd((ADJgNativeExpressAdInfo) adADJgNativeAdInfo);
                    }
                }
            }

            @Override
            public void onAdExpose(ADJgNativeAdInfo adADJgNativeAdInfo) {
                Log.d(ADJgDemoConstant.TAG, "onAdExpose: " + adADJgNativeAdInfo.hashCode());
                manager.onAdExpose(
                        FlutterNativeAd.this,
                        adADJgNativeAdInfo.getPlatform(),
                        adADJgNativeAdInfo.getEcpmPrecision(),
                        adADJgNativeAdInfo.getECPM()
                );
            }

            @Override
            public void onAdClick(ADJgNativeAdInfo adADJgNativeAdInfo) {
                Log.d(ADJgDemoConstant.TAG, "onAdClick: " + adADJgNativeAdInfo.hashCode());
                manager.onAdClick(
                        FlutterNativeAd.this,
                        adADJgNativeAdInfo.getPlatform(),
                        adADJgNativeAdInfo.getEcpmPrecision(),
                        adADJgNativeAdInfo.getECPM()
                );
            }

            @Override
            public void onAdClose(ADJgNativeAdInfo adADJgNativeAdInfo) {
                Log.d(ADJgDemoConstant.TAG, "onAdClose: " + adADJgNativeAdInfo.hashCode());
                manager.onAdClose(
                        FlutterNativeAd.this,
                        adADJgNativeAdInfo.getPlatform(),
                        adADJgNativeAdInfo.getEcpmPrecision(),
                        adADJgNativeAdInfo.getECPM()
                );
            }

            @Override
            public void onAdFailed(ADJgError adADJgError) {
                if (adADJgError != null) {
                    Log.d(ADJgDemoConstant.TAG, "onAdFailed: " + adADJgError.toString());
                    manager.onAdFailed(FlutterNativeAd.this, adADJgError);
                }
            }
        });
        adADJgNativeAd.loadAd(adPosId);
    }

    private void showNativeAd(ADJgNativeExpressAdInfo nativeExpressAdInfo) {
        if (!ADJgAdUtil.adInfoIsRelease(nativeExpressAdInfo)) {
//            NativeAdAdapter.setVideoListener(nativeExpressAdInfo);
            // 当前是信息流模板广告，getNativeExpressAdView获取的是整个模板广告视图
            final View nativeExpressAdView = nativeExpressAdInfo.getNativeExpressAdView(flContainer);
            // 将广告视图添加到容器中的便捷方法
            ADJgViewUtil.addAdViewToAdContainer(flContainer, nativeExpressAdView);

            // 渲染广告视图, 必须调用, 因为是模板广告, 所以传入ViewGroup和响应点击的控件可能并没有用
            // 务必在最后调用
            nativeExpressAdInfo.render(flContainer);

            nativeExpressAdView.requestLayout();
            flContainer.requestLayout();

            new Handler(Looper.getMainLooper()).post(new Runnable() {
                @Override
                public void run() {
                    int[] size = unDisplayViewSize(flContainer);
                    // 其他渠道
                    callbackReceived(size);
                }
            });
        }
    }

    @Override
    public void release() {
        Log.d(ADJgDemoConstant.TAG, " nativeAd release ");
        if (adADJgNativeAd != null) {
            adADJgNativeAd.release();
            adADJgNativeAd = null;
        }
        flContainer.removeAllViews();
    }

    @Override
    public View getView() {
        return flContainer;
    }

    @Override
    public void dispose() {

    }

    public int[] unDisplayViewSize(View view) {
        int size[] = new int[2];
        int width = View.MeasureSpec.makeMeasureSpec(0,
                View.MeasureSpec.UNSPECIFIED);
        int height = View.MeasureSpec.makeMeasureSpec(0,
                View.MeasureSpec.UNSPECIFIED);
        view.measure(width, height);
        size[0] = view.getMeasuredWidth();
        size[1] = ADJgDisplayUtil.px2dp(view.getMeasuredHeight());

        Log.d("unDisplayViewSize", "width:" + width + " height:" + height);
        Log.d("unDisplayViewSize", "width:" + view.getMeasuredWidth() + " height:" + view.getMeasuredHeight());
        return size;
    }

    public void callbackReceived(int[] size) {
        // 小于10dp默认用传入的adHeight
        if (size[1] <= 10) {
            // adHeight为0时，默认150dp
            if (adHeight == 0) {
                adHeight = 150;
            }
            manager.onNativeReceived(
                    FlutterNativeAd.this,
                    ADJgDisplayUtil.px2dp(adWidth),
                    ADJgDisplayUtil.px2dp(adHeight)
            );
        } else {
            manager.onNativeReceived(FlutterNativeAd.this, ADJgDisplayUtil.px2dp(adWidth), size[1]);
        }
    }
}
